package top.zhdev.community.service.impl;

import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.stereotype.Service;
import top.zhdev.community.service.LikeService;
import top.zhdev.community.utils.RedisKeyUtil;

import javax.annotation.Resource;

@Service
public class LikeServiceImpl implements LikeService {
    @Resource
    private RedisTemplate redisTemplate;

    /**
     * 查询某个实体（帖子，评论等）点赞数量
     * @param entityType
     * @param entityId
     * @return
     */
    @Override
    public long getEntityLikeCount(int entityType, int entityId) {
        String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType,entityId);
        // opsForSet set是redis中的一种类型，size是获取变量中值的长度
        return redisTemplate.opsForSet().size(entityLikeKey);
    }

    /**
     * 查询某人对某实体的点赞状态
     * @param entityType
     * @param entityId
     * @param userId
     * @return
     */
    @Override
    public int getEntityLikeStatus(int entityType, int entityId, Integer userId) {
       String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType, entityId);
       return redisTemplate.opsForSet().isMember(entityLikeKey,userId)?1:0;
    }

    /**
     *
     * 对实体（帖子，回复）点赞，对相应的用户加赞
     * @param userid 点赞的人
     * @param entityType
     * @param entityId
     * @param entityUserId  被赞的人，即作者
     */
    @Override
    public void like(Integer userid, int entityType, int entityId, int entityUserId) {
        // redis事务
        redisTemplate.execute(new SessionCallback() {
            @Override
            public Object execute(RedisOperations operations) throws DataAccessException {
                String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType,entityId);
                String userLikeKey = RedisKeyUtil.getUserLikeKey(entityUserId);
                //opsForSet().isMember  检查给定的元素是否在变量中
                boolean isMember = redisTemplate.opsForSet().isMember(entityLikeKey,userid);
                // 多个更新操作，需要事务
                operations.multi();
                if(isMember){
                    // 取消赞
                    redisTemplate.opsForSet().remove(entityLikeKey,userid);
                    // 减少对应的点赞数量
                    redisTemplate.opsForValue().decrement(userLikeKey);
                }else{
                    redisTemplate.opsForSet().add(entityLikeKey,userid);
                    redisTemplate.opsForValue().increment(userLikeKey);
                }
                return operations.exec();
            }
        });
    }

    /**
     * 获取该用户获得的点赞数量,用户在个人主页获取查看收获了多少个赞
     * @param userId
     * @return
     */
    @Override
    public int getUserLikeCount(int userId) {
        String userLikeKey = RedisKeyUtil.getUserLikeKey(userId);
        Integer count = (Integer) redisTemplate.opsForValue().get(userLikeKey);
        return count == null ? 0 : count.intValue();
    }
}
